package com.zeropoint.demo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.SecureUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zeropoint.demo.exception.AuthorityException;
import com.zeropoint.demo.exception.SelectException;
import com.zeropoint.demo.exception.UserLoginException;
import com.zeropoint.demo.mapper.UserMapper;
import com.zeropoint.demo.pojo.MenuPO;
import com.zeropoint.demo.pojo.RolePO;
import com.zeropoint.demo.pojo.UserPO;
import com.zeropoint.demo.pojo.vo.RegionVO;
import com.zeropoint.demo.pojo.vo.UserVO;
import com.zeropoint.demo.service.UserService;
import com.zeropoint.demo.util.JwtUtil;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.management.relation.Role;
import javax.servlet.http.HttpServletRequest;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;


    @Override
    public HashMap<String, Object> userLogin(UserPO userPO) throws UserLoginException {

        UserPO user = userMapper.getUserByName(userPO.getUsername());
        // 验证账号
        if(user == null){
            throw new UserLoginException("账号不存在！");
        }
        // 验证登录状态
        if(user.getState() == 0){
            throw new UserLoginException("该用户已被封禁，请联系上级管理员！");
        }
       /* // 验证密码 MD5
        String s = SecureUtil.md5(userPO.getPassword());
        if(!user.getPassword().equals(s)){
            throw new UserLoginException("密码错误！");
        }*/

        // 验证密码 Base64(明文验证)
        byte[] decodedBytes = Base64.getDecoder().decode(user.getPassword());
        String decodedString = new String(decodedBytes);
        if(!decodedString.equals(userPO.getPassword())){
            throw new UserLoginException("密码错误！");
        }

        // 登录成功
        HashMap<String,Object> map = new HashMap<>();
        UserVO userVO = userMapper.seleteUserInformation(user.getUid());

        // 下发Token
        String token = JwtUtil.sign(user.getUsername());


        // 组装数据
        map.put("user",userVO);
        map.put("token",token);

        return map;
    }

    @Override
    public List<MenuPO> getMenus() {
       /* String token = (String)SecurityUtils.getSubject().getPrincipal();
        String username = JwtUtil.getClaim(token);
        UserPO user = userMapper.getUserByName(username);*/

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        UserPO user =(UserPO) request.getAttribute("user");

        return userMapper.selectMenuByUserId(user.getUid());
    }


    @Override
    public  PageInfo<UserVO> getUsers(Integer currentPage, Integer pageSize) {

        /*String token = (String)SecurityUtils.getSubject().getPrincipal();
        String username = JwtUtil.getClaim(token);
        UserPO user = userMapper.getUserByName(username);*/

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        UserPO user =(UserPO) request.getAttribute("user");

        // 开启分页
        PageHelper.startPage(currentPage,pageSize);
        List<UserVO> users = userMapper.selectUserByRole(user.getUid());
        for (UserVO userVO : users) {
            // 把密文变成明文
            byte[] decodedBytes = Base64.getDecoder().decode(userVO.getPassword());
            String decodedString = new String(decodedBytes);
            userVO.setPassword(decodedString);
        }
        PageInfo<UserVO> userVOPageInfo = new PageInfo<>(users);
        //userVOPageInfo.setList(users);
        return  userVOPageInfo;
    }

    @Override
    public List<String> getRegions(String regionName) throws SelectException {

        String token = (String)SecurityUtils.getSubject().getPrincipal();
        String username = JwtUtil.getClaim(token);
        int roleId = userMapper.selectRoleIdByUserName(username);

        if(roleId != 0 && roleId != 4){
            switch (roleId){
                case 1:
                    return userMapper.selectProvinces();
                case 2:
                    return userMapper.selectCityes(regionName);
                case 3:
                    return userMapper.selectTowns(regionName);
            }
        }else{
            throw new SelectException("查询失败！");
        }

        return null;
    }

    @Override
    @Transactional
    public UserVO saveUser(UserVO userVO) {

        UserVO userVO1 = new UserVO();
        userVO.setRoleState(true);
        BeanUtils.copyProperties(userVO,userVO1);

        String password = userVO.getPassword();
        // MD5加密密码
        // String s = SecureUtil.md5(password);
        // Base64加密
        String s = Base64.getEncoder().encodeToString(password.getBytes());
        userVO.setPassword(s);

        int id = userMapper.insertUser(userVO);
        userMapper.insertUserRole(userVO);
        userVO.setUid(id);
        return userVO1;

    }

    @Override
    @Transactional
    public String modifyUserInformation(HashMap<String, String> map) throws UserLoginException {

        String username = map.get("username");
        String oldPassword = map.get("oldPassword");
        String newPassword = map.get("newPassword");

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        UserPO user =(UserPO) request.getAttribute("user");


        // 要判断权限
        // 验证密码 Base64(明文验证)
        byte[] decodedBytes = Base64.getDecoder().decode(user.getPassword());
        String decodedString = new String(decodedBytes);
        if(!decodedString.equals(oldPassword)){
            throw new UserLoginException("密码错误！");
        }

        user.setUsername(username);
        /*// MD5加密新密码
        user.setPassword(SecureUtil.md5(newPassword));*/
        // Base64加密
        String s = Base64.getEncoder().encodeToString(newPassword.getBytes());
        user.setPassword(s);
        // 修改信息
        userMapper.updateUser(user);

        // 修改后，重新下发 Token
        // 下发Token
        String token = JwtUtil.sign(user.getUsername());
        return token;

    }

    @Override
    public void modifyUserState(Integer otherId, String way) throws AuthorityException {

        // 只允许修改比自己角色低的，不允许修改同级的
        // 查询出当前用户的角色id
        /*String token = (String)SecurityUtils.getSubject().getPrincipal();
        String username = JwtUtil.getClaim(token);
        UserPO user = userMapper.getUserByName(username);*/

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        UserPO user =(UserPO) request.getAttribute("user");

        List<RolePO> roles = userMapper.getRoleById(user.getUid());
        RolePO rolePO = roles.get(0);
        // 查询出被修改用户的角色id
        List<RolePO> otherRoles = userMapper.getRoleById(otherId);
        RolePO rolePO1 = otherRoles.get(0);

        if(rolePO.getRoleId() == rolePO1.getRoleId()){
            throw new AuthorityException("你无权修改该用户的信息!");
        }

        // 根据方式来进行修改（修改/删除）
        if("modify".equals(way)){
            userMapper.updateUserDate(otherId);
        }else if("delete".equals(way)){
            userMapper.deleteUser(otherId);
        }else{
            throw new AuthorityException("无此项操作！");
        }
    }

    @Override
    public UserVO getUserInformation(Integer userId) throws AuthorityException {

        UserVO userVO = userMapper.seleteUserInformation(userId);
        if(userVO == null) throw new  AuthorityException("该用户不存在！");
        // 解密密码
        byte[] decodedBytes = Base64.getDecoder().decode(userVO.getPassword());
        String decodedString = new String(decodedBytes);
        userVO.setPassword(decodedString);
        return userVO;
    }

    @Override
    public UserVO selectUserInfo() {

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        UserPO user =(UserPO) request.getAttribute("user");

        return  userMapper.seleteUserInformation(user.getUid());
    }
}
